package com.lindenvalley.de.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

import com.lindenvalley.de.content.Sections;
import com.lindenvalley.de.content.user.User;
import com.lindenvalley.de.parsers.SimpleXmlParser;

import android.util.Log;

public class WorkServer {
	
	private DefaultHttpClient httpClient;
	private HttpGet requestGet;	
	private HttpPost requestPost;
	private HttpResponse response;
	private static final String HOST = "http://zwischenpruefung.lindenvalley.ch/";
	private static final String LOGIN_SCRIPT = "api/users/users/get_access_session/xml";
	private static final String SEND_DATA_LEARNING_SCRIPT = "api/learning/xmlmobile/synhronize_rounds/";
	private static final String SEND_DATA_EXAM_SCRIPT = "api/learning/xmlmobile/synhronize_exam/";
	private static final String INIT_SCRIPT = "start.php";
	public static final String NOT_CONNECT = "notconnect";
	private StringBuffer sb;
	private URI uri;
	private static WorkServer instance;
	private final String TAG = getClass().getSimpleName();
	public static final String SUCCESS_VALUE = "success\n";
	public static final String DENY_VALUE = "denay\n";
	private CookieStore cookieStore;
    private HttpContext localContext;
	private Sections sections;
	private User user;
	
	
	private WorkServer() {
		httpClient = new DefaultHttpClient();
		sb = new StringBuffer("");
		initSession();
	}
	
	public static WorkServer getInstance(){
		if (instance == null){
			synchronized (WorkServer.class){
				if (instance == null){
					instance = new WorkServer();
				}
			}
		}
		return instance;
	}


	public Object doLogin(String userName, String password){
		Object result = DENY_VALUE;		
		if (userName != null && password != null){
			try{
				uri = URI.create(HOST + LOGIN_SCRIPT);
				requestPost = new HttpPost(uri);
				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
				nameValuePairs.add(new BasicNameValuePair("login", userName));
				nameValuePairs.add(new BasicNameValuePair("password", password));
				try {
					requestPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
					result = doRequest(requestPost);
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
								
				if (result != null && ((String)result).length() > 0 && !DENY_VALUE.equals(result)){
					SimpleXmlParser<User> parser = new SimpleXmlParser<User>(User.class);
					User user = parser.parse((String)result);
					if (user != null)
						result = user;					
				} else {
					result = DENY_VALUE;
				}
				
			} catch (IllegalArgumentException ex){
				ex.printStackTrace();
			}
						
		} 
		Log.i("LOGIN", "RESULT     " + result);
		return result;
	}
	
	public Object synchLearingData(String xmlData, int userId){
		if (xmlData != null && xmlData.length() > 0){
			uri = URI.create(HOST + SEND_DATA_LEARNING_SCRIPT + String.valueOf(userId) + "/");
			return sendData(uri, xmlData);
		} else
			return null;
		
	}
	
	public Object synchExamData(String xmlData, int userId){
		if (xmlData != null && xmlData.length() > 0){
			Log.i(TAG, xmlData);
			uri = URI.create(HOST + SEND_DATA_EXAM_SCRIPT + String.valueOf(userId) + "/");
			return sendData(uri, xmlData);
		} else
			return null;
		
		
	}
	
	private Object sendData(URI uri, String xmlData){
		Object result = DENY_VALUE;
		requestPost = new HttpPost(uri);
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		nameValuePairs.add(new BasicNameValuePair("xml", xmlData));
		try {
			requestPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			result = doRequest(requestPost);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	
	
	public void destroy(){
		if (instance != null)
			instance = null;
	}
	
	private void initSession(){
		uri = URI.create(HOST + INIT_SCRIPT);
		requestGet = new HttpGet(uri);		
		cookieStore = new BasicCookieStore();

	    // Create local HTTP context
	    localContext = new BasicHttpContext();
	    // Bind custom cookie store to the local context
	    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

		doRequest(requestGet);
	}
	
	private synchronized String doRequest(HttpUriRequest uriRequest){
		String result = null;
		try {
			Log.i(TAG, "URL request: " + uriRequest.getURI());
			response = httpClient.execute(uriRequest, localContext);
			BufferedReader in = new BufferedReader
            (new InputStreamReader(response.getEntity().getContent()));	            
            String line = "";
            sb.setLength(0);
            sb.trimToSize();
//            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            in.close();
            result = sb.toString();
			
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
			result = NOT_CONNECT;
		}
		return result;
	}
	
	public void clearData(){
		sections.getSection().clear();
		sections = null;
	}

	/**
	 * @param sections the sections to set
	 */
	public void setSections(Sections sections) {
		this.sections = sections;
	}

	/**
	 * @return the sections
	 */
	public Sections getSections() {
		return sections;
	}

	/**
	 * @param user the user to set
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * @return the user
	 */
	public User getUser() {
		return user;
	}

}
